package br.com.felinelayer.server;

import br.com.felinelayer.common.Communication;
import br.com.felinelayer.common.ICommunicationListener;
import br.com.felinelayer.common.Message;
import br.com.felinelayer.server.application.Application;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Vanius Roberto Bittencourt
 */
public final class ClientServer implements ICommunicationListener {

    public ClientServer(Socket socket) {
        setSocket(socket);
    }
    private Socket socket;
    private Communication communication;

    public void setSocket(Socket socket) {
        this.socket = socket;
        if (this.communication == null) {
            setCommunication(new Communication(this));
        }
    }

    public Communication getCommunication() {
        return communication;
    }

    public void setCommunication(Communication communication) {
        this.communication = communication;
        this.communication.isServer = true;
    }
    private Application application;

    public void setApplication(Application application) {
        this.application = application;
        application.setClient(this);
        Message c = new Message("ConnectingApplicationName");
        c.setValueByName("ApplicationName", application.getApplicationName());
        processMessageReceived(c);
    }

    @Override
    public Socket getSocket() {
        return socket;
    }

    public void disconnect() {
        communication.disconnect();
    }

    public void sendMessage(Message message) {
        communication.sendMessage(message);
    }

    public ClientServer beginBatch() {
        communication.beginBatch();
        return this;
    }

    public boolean inBacth() {
        return communication.inBatch();
    }

    public ClientServer endBatch() {
        communication.endBatch();
        return this;
    }

    public Message inquire(Message message) {
        return communication.inquire(message);
    }

    // ESSTE MÉTODO É EXECUTADO NUMA THREAD SEPARADA DA RECEPÇÃO DO SOCKET.
    // SE SIM, ENTÃO A RECEPÇÃO DO CLIENT PRECISAR CRIAR UM RUNNABLE E PASSAR PARA O INVOKELATER?
    // REVISAR ESTE processMessageReceived COM O DO client.Client
    @Override
    public void processMessageReceived(Message message) {
        try {
            //synchronized 
// deve ter if com os comandos
            if (application != null) {
                application.messageReceived(message);
            }
            communication.finishMessageReceived(message);
        } catch (Exception ex) {
            Logger.getLogger(ClientServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
